package com.example.demo.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.example.demo.exception.IMIDHadCreatedException;
import com.example.demo.exception.IMIDNotExistException;
import com.example.demo.redis.RedisKey;
import com.example.demo.service.IMService;
import com.example.demo.tencent.TencentCloudIMProperties;
import com.example.demo.tencent.TencentCloudIMUserSignUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class TencentIMService implements IMService {
    private final RedisTemplate<String, Object> redisTemplate;

    public TencentIMService(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public Boolean isOriginIdUsed(String originId) throws IOException {
        HttpURLConnection connection = createConnection(TencentCloudIMProperties.USER_QUERY_URL.getValue());
        DataOutputStream out = new DataOutputStream(connection.getOutputStream());

        JSONObject user1 = new JSONObject();
        user1.put("UserID", originId);
        List<JSONObject> userList = new ArrayList<>();
        userList.add(user1);
        JSONObject obj = new JSONObject();
        obj.put("CheckItem", userList);

        // 向腾讯请求传入编码为UTF-8格式的json数据
        out.write(obj.toString().getBytes(StandardCharsets.UTF_8));
        out.flush();
        out.close();

        // 获得服务器返回的结果
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        String lines;
        StringBuffer sb = new StringBuffer("");
        while ((lines = reader.readLine()) != null) {
            lines = new String(lines.getBytes(), StandardCharsets.UTF_8);
            sb.append(lines);
        }
        reader.close();
        System.out.println(sb);
        // 将BufferedReader转换为String 类型，然后进行解析
        String returnString = sb.toString();

        JSONObject jObject = JSONObject.parseObject(returnString);
        JSONArray resultArray = jObject.getJSONArray("ResultItem");
        System.out.println(resultArray.toJSONString());
        List<IMQueryResult> results = JSON.parseArray(resultArray.toJSONString(), IMQueryResult.class);

        return  results != null &&
                results.size() == 1 &&
                results.get(0).AccountStatus.equals("Imported");
    }


    /**
     *
     * @param originId 用户在app系统中的唯一id
     * @return
     * @throws IMIDHadCreatedException
     * @throws IOException
     */
    @Override
    public String generateIMId(String originId) throws IMIDHadCreatedException, IOException {
        HttpURLConnection connection = createConnection(TencentCloudIMProperties.USER_IMPORT_URL.getValue());

        DataOutputStream out = new DataOutputStream(connection.getOutputStream());
        JSONObject obj = new JSONObject();
        obj.put("UserID", originId);

        // 向腾讯请求传入编码为UTF-8格式的json数据
        out.write(obj.toString().getBytes(StandardCharsets.UTF_8));
        out.flush();
        out.close();

        // 获得服务器返回的结果
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        String lines;
        StringBuffer sb = new StringBuffer("");
        while ((lines = reader.readLine()) != null) {
            lines = new String(lines.getBytes(), StandardCharsets.UTF_8);
            sb.append(lines);
        }
        reader.close();
        System.out.println(sb);
        // 将BufferedReader转换为String 类型，然后进行解析
        String returnString = sb.toString();

        JSONObject jObject = JSONObject.parseObject(returnString);
        String ActionStatus = jObject.get("ActionStatus").toString();

        // 腾讯IM不返回 accId，直接将 originId 返回即可
        return originId;
    }

    @Override
    public String queryIMId(String originId) throws IMIDNotExistException, IOException {
        if (isOriginIdUsed(originId)) {
            // 腾讯IM 不返回accId，默认accId 使用 originId。
            return originId;
        } else {
            throw new IMIDNotExistException("originId 为在 IM 系统中创建对应的appId");
        }
    }

    @Override
    public String getIMToken(String originId) throws IMIDNotExistException {
        if (originId == null || originId.equals("")) {
            throw new IMIDNotExistException("originId 为 null 或 空字符串");
        }

        String key = RedisKey.IM_SIGN.replace("{id}", originId);
        String sign = null;
        // key 有效且未过期
        if (redisTemplate.hasKey(key) &&
            redisTemplate.opsForValue().getOperations().getExpire(key) > 0) {
            sign = (String) redisTemplate.opsForValue().get(key);
        } else {
            // accId 与 originId 一致
            String accId = originId;
            long expire = Long.parseLong(TencentCloudIMProperties.SIGN_EXPIRE_SECONDS.getValue());
            sign = TencentCloudIMUserSignUtil.genUserSig(accId, expire);
            redisTemplate.opsForValue().set(key, sign, expire, TimeUnit.SECONDS);
        }

        return sign;
    }

    private HttpURLConnection createConnection(String baseUrl) throws IOException {
        URL url = null;

        try {
            url = new URL(fillURLWithBasicParams(baseUrl));
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setRequestMethod("POST");
            connection.setUseCaches(false);
            connection.setInstanceFollowRedirects(true);
            connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
            connection.connect();
            return connection;

        }catch (IMIDNotExistException e) {
            e.printStackTrace();
            return null;
        }
    }

    private String fillURLWithBasicParams(String baseUrl) throws IMIDNotExistException {
        String sdkAppId = TencentCloudIMProperties.SDK_APP_ID.getValue();
        String identifier = TencentCloudIMProperties.SDK_APP_IDENTIFIER.getValue();
        String userSign = getIMToken(identifier);
        Random random = new Random();
        int rand = random.nextInt();
        return String.format(baseUrl, sdkAppId, identifier, userSign, rand);
    }

    /**
     * 用于接受查询用户是否导入IM系统的Response实体
     */
    public static class IMQueryResult implements Serializable {
        private String UserID;
        private int ResultCode;
        private String ResultInfo;
        private String AccountStatus;

        public IMQueryResult(){}

        public String getUserID() {
            return UserID;
        }

        public void setUserID(String userID) {
            UserID = userID;
        }

        public int getResultCode() {
            return ResultCode;
        }

        public void setResultCode(int resultCode) {
            ResultCode = resultCode;
        }

        public String getResultInfo() {
            return ResultInfo;
        }

        public void setResultInfo(String resultInfo) {
            ResultInfo = resultInfo;
        }

        public String getAccountStatus() {
            return AccountStatus;
        }

        public void setAccountStatus(String accountStatus) {
            AccountStatus = accountStatus;
        }
    }
}
